/***************************************************************************************************
 *Copyright(C),2010-2016,Sumscope
 *FileName	:  DictExport.cpp
 *Author	:  scofined.qi
 *Version	:  1.0
 *Date		:  2017/04/19
 *Desc		:  用于将新字典导出为旧字典的格式:cod,文本文件,|分割
 *Relation :
 *Others	:
 *Function :
 *History	:
 ***************************************************************************************************/
#include "DictExport.h"

#include <core/Utility.h>

#ifdef WIN32
#define BASSERT assert
#else
#define BASSERT  //
#endif

namespace qb {
namespace ht {
DictExport::DictExport(int capcity, int precision, const std::string& tag)
    : m_size(0),
      m_file(nullptr),
      m_capcity(capcity),
      m_col_added(0),
      m_encrypt(tag.size() > 0),
      m_tagger(0),
      m_hasconverter(false) {
  m_buffer = new char[m_capcity];
  memset(m_buffer, 0, m_capcity);
  memset(m_double_format, 0, 32);
  FMTBUF(m_double_format, "%%.%df", precision);
  if (m_encrypt) m_tagger = new qb::base::StringAes(tag.c_str());
}

DictExport::~DictExport() {
  Flush();
  if (m_buffer) delete[] m_buffer;
  if (m_file) {
    m_file->flush();
  }
  if (m_file) {
    m_file->close();
    delete m_file;
    m_file = nullptr;
  }
  if (m_tagger) delete m_tagger;
}

bool DictExport::Init(const char* fullFileName) {
  m_file = new QFile(fullFileName);
  if (m_file == 0) {
    m_file = NULL;
    return false;
  }
  m_file->open(QIODevice::ReadWrite);
  m_file->reset();

  return true;
}

void DictExport::AddLineEnd() {
  if (m_encrypt) {
    AddString("\n", 1);
    int size = m_tagger->EncryptInPlace(m_buffer, m_size, m_capcity);
    m_size = size;
    Flush();
    m_col_added = 0;
    return;
  }
  AddString("\r\n", 2);
  m_col_added = 0;
}

void DictExport::AddData(kDataType type, int offset, const char* data,
                         int len) {
  char temp[32] = {0};
  kConvertType convert = kConvertTypeNone;
  if (m_col_added > 0) AddString("#", 1);
  switch (type) {
    case kDataTypeInt:
#ifdef WIN32
      _itoa_s(*(int*)data, temp, 10);
#else
      sprintf(temp, "%d", *(int*)data);
#endif
      convert = GetConvertTypeByOfffset(offset);
      if (convert == kConvertTypeBlank) {
        if (*(int*)data <= 0) {
          // AddString(" ", 1);//空白为没有字符
        } else
          AddString(temp, strlen(temp));
      } else
        AddString(temp, strlen(temp));
      break;
    case kDataTypeDouble:
      len = FMTBUF(temp, m_double_format, *(double*)data);
      AddString(temp, len);
      break;
    case kDataTypeChar:
      // 原始BondList中的char都按照数字保存,如NY保存为78,89
#ifdef WIN32
      _itoa_s(*data, temp, 10);
#else
      sprintf(temp, "%d", *data);
#endif
      convert = GetConvertTypeByOfffset(offset);
      if (convert == kConvertTypeYesNo)
        AddString(data, 1);
      else
        AddString(temp, strlen(temp));
      break;
      // AddString(data, 1); break;
    case kDataTypeCharArray:
      AddString(data, strlen(data));
      break;
    default:
      BASSERT(0);
      break;
  }
  m_col_added++;
}

void DictExport::AddString(const char* str, int len) {
  if (str && len > 0) {
    if (len + m_size >= m_capcity) Flush();
    BASSERT(len + m_size < m_capcity);
    memcpy(m_buffer + m_size, str, len);
    m_size += len;
  }
}

void DictExport::Flush() {
  if (m_buffer && m_size > 0 && m_file) {
    m_file->write(m_buffer, m_size);
  }
  if (m_buffer && m_capcity > 0) memset(m_buffer, 0, m_capcity);
  m_size = 0;
}

void DictExport::AddConverter(const char* name, int offset, kConvertType type) {
  m_hasconverter = true;
  while ((int)m_converts.size() <= offset) {
    m_converts.push_back(kConvertTypeNone);
  }
  m_converts[offset] = type;
}

}  // namespace ht
}  // namespace qb
